home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
yerk
/
mps231ss.hqx
/
Mops source
/
More classes
/
MW documents
/
G&HFmod.txt
next >
Wrap
Text File
|
1992-05-07
|
13KB
|
509 lines
\ This module handles graphics, headers, footers and footnotes.
\ We don't do anything terribly clever with graphics. On input, we ignore
\ them except we retain the 01 character in the text wherever a graphic occurs.
\ On output, we just generate an empty default graphic wherever the text has
\ an 01.
hex
table GRAPHIC_INFO
FFFF w, E , 0 , 0 w, 48 w, 48 w,
end_table
table GRAPHIC_FMT
0040 w, 0 w, 0 w, 0 w, 0300 w, 0 w,
end_table
table SPEC_FMT
0040 w,
end_table
decimal
: ?ALIGN_TEXT
size: text 1 and 0EXIT
pos: text 0 +: text >pos: text ;
: MARK_SPEC { \ code offs -- }
pos: text -> offs \ Save pos: text
?align_text true -> GHF?
offs false find_posn: fmt_run offs new_item: fmt_run
0 >nxtc: fmt_run $ 40 >nxtc: fmt_run
lim: text 2+ >nxtw: fmt_run
6 skip: fmt_run
$ FFFF >nxtw: fmt_run \ Store dummy font #
1st: text 1- dup -> code >nxtc: fmt_run \ And code #
1 skip: fmt_run
code NIF graphic_info add: text THEN
offs >pos: text ; \ Restore pos: text
: MARK_SP \ Exported. Called on output, after FIXUP_HFS.
text_only? ?EXIT
reset: text reset: fmt_run
1 4 selRange: utTbl
BEGIN
text&hf_len >lim: text
utTbl scan: text 0EXIT
step: text mark_spec 1 skip: text
AGAIN ;
\ ==== Sections, headers and footers and footnotes ====
false value 1st_SPECIAL?
0 value HF_FLGS
0 value HF_OFFS
0 value HF_STRT
0 value HF_POS
0 value HF_LIM
0 value HF_CODE
0 value HF_DISPL
0 value SECT_OFFS_POS
0 value SECT_DESC_POS
0 value FTN_OFFS_POS
hex
table SECT_INDIC
0241 w, 00 c,
\ 0208 w, 00 c, \ 4
\ 0E3C w, 02E1 w, 3D06 w, A541 w, 0044 w, 02E1 w, 4502 w, E1 c,
end_table
table SECT_INDIC+1st_SPEC
\ 04370141 , 00 c, \ 4 ****EXPERIMENTING
\ 0208 w, 00 c,
0A37 w, 013c w, 02e1 w, 3d06 w, a541 w, 00 c,
\ It seems with Word 4 opening a Word 3 document, we need all this stuff!!
end_table
table HF_STYLES
F4F4F3F3 , F4F3 w,
end_table
table HF_MASKS
01020408 , 1020 w,
end_table
decimal
scon 2RETS "RR" & R RET instead
scon 4RETS "RRRR" & R RET instead
\ ========== Utility words ===========
: SELHFS
clear: utTbl $ 10 $ 15 selRange: utTbl ;
: INSERT_MK \ ( c -- ) Inserts the given mark in text.
\ pos: text marks the spot.
pos: text dup 0 1 fixup: fmt_run 0 1 fixup: para_run
1 ++> text&hf_len 1 ++> HF_displ
pos: text real_text_len < --> real_text_len
1 ++> #insrtd
chinsert: text ;
: REMOVE_MK
pos: text dup 1 0 fixup: fmt_run 1 0 fixup: para_run
1 deleten: text -1 ++> text&hf_len -1 ++> #insrtd ;
\ ============ Input ============
\ SPEC_IN (exported) is called when a "special" format is detected.
: SPEC_IN { offs -- }
fmt c@ $ C >= ?EXIT \ Out if it's a graphic
\ unmpd_old >pos: theFile
\ unmpd_new >lim: theFile
\ theFile ->: sect_str \ *** may not need this - see next word.
;
: GET_HF_FLGS
sect_desc_pos >pos: sect_offsets
len: sect_offsets 6 < IF 0 -> HF_flgs EXIT THEN
theFile copyto: sect_str
2 skip: sect_offsets
4 nxtN: sect_offsets
6 ++> sect_desc_pos
dup 0< IF drop EXIT THEN \ 4
hdr_len - ( #insrtd + ) >pos: sect_str \ ***chk OK
len: sect_ov_str
IF
sect_offs_pos >pos: sect_offsets 4 ++> sect_offs_pos
nxtL: sect_offsets
sect_desc_pos >pos: sect_offsets
^1st: sect_ov_str @ 1+ =
IF ( use override value )
4 skip: sect_ov_str
nxtW: sect_ov_str -> HF_flgs EXIT
THEN
THEN
count: sect_str \ Info for this section
mw4?
IF $ 80 ELSE $ 41 THEN
chsearch: sect_str
NIF 0
ELSE 2 more: sect_str last: sect_str
THEN -> HF_flgs ;
: MK_HF \ ( n -- )
( n ) $ 10 or ^1st: text c! ;
\ That had better have been a RET we wiped out!
: >NXTHF
len: theFile
IF 4 nxtN: theFile HF_strt + HF_displ +
ELSE text&HF_len
THEN
1- >pos: text nolim: text ;
: MARK_HFS_FOR_SECT
get_HF_flgs HF_flgs
IF
6 0 DO
HF_masks drop i + c@
HF_flgs and IF i mk_HF >nxtHF THEN
LOOP
THEN
sect_end_mark insert_mk ;
: SETUP_SECT_OFFS \ Skips the offsets to the section markers in the
\ text, and gets us to the offsets into the
\ section info.
reset: sect_ov_str
4 len: sect_offsets min -> sect_offs_pos
BEGIN
len: sect_offsets 4 < ?EXIT
4 nxtN: sect_offsets text&hf_len #insrtd - >=
UNTIL
pos: sect_offsets -> sect_desc_pos ;
: MARK_FTN \ Exported.
reset: fmt_run reset: para_run reset: ftn_markers reset: text
ftn_mark ^1st: text real_text_len + ftn_len + 2- c!
\ That should have been a RET we wiped out!
BEGIN
len: ftn_markers 8 <= ?EXIT
nxtL: ftn_markers #insrtd + >pos: text
ftn_mark insert_mk
nxtL: ftn_offsets real_text_len + 1- >pos: text
ftn_mark ^1st: text c! \ Should have been a RET!
AGAIN ;
: MARK_HFS \ Exported. Called last.
real_text_len 1- >pos: text nolim: text
reset: fmt_run reset: para_run \ For insert_mk following
text_end_mark insert_mk \ Comes before final RET
0 -> hf_displ pos: text 1+ -> HF_strt
setup_sect_offs
>nxtHF
BEGIN
len: sect_offsets
WHILE
mark_HFs_for_sect
REPEAT ;
\ =========== Output ============
0 value HF_CNT
: ADD_SECT_INFO
HF_flgs dup +: src \ Leave flags in src for SECT_STR_OUT
0EXIT
HF_flgs $ F > \ Is there a "1st" hdr/ftr?
IF sect_indic+1st_spec ELSE sect_indic THEN
add: tmp
HF_flgs ^1st: tmp 1- c! ;
: (HFS_FOR_SECT) { \ hf# -- }
0 -> HF_flgs
len: text 0EXIT \ Out if no hdrs/ftrs for this sect
lim: text ( save - used in loop below )
BEGIN
1st: text $ 10 - -> hf#
HF_masks drop hf# + c@
HF_flgs or -> HF_flgs
RET >nxtc: text
pos: text real_text_len - +L: HF_offsets
pos: text new_item: para_run
hf_styles drop hf# + c@ \ hdr or ftr style#
^1st: para_run w! skip_info: para_run
utTbl scan: text
\ Now we ensure that this HF ends with RET - WordFormat could have
\ wiped it out!
len: text ( just in case )
IF RET ^1st: text len: text + 1- c! THEN
step: text
over >lim: text
NUNTIL
drop ;
: S+HF { \ len #left -- offs }
1st: tmp 1+ -> len \ Length of next item
$ 80 lim: text $ 7F and - -> #left
\ # bytes left in text block
len #left >
IF \ Not enough room - go to next block
pad #left add: text
THEN
pos: text hdr_len + \ Return result
len >len: tmp tmp $add: text
step: tmp ;
: SECT_STR_OUT
reset: tmp reset: src end: text
BEGIN
len: src 0EXIT
nxtc: src \ HF flags for next section
IF S+HF \ Section has hdrs/footers
ELSE -1
THEN
3 +W: sect_offsets +L: sect_offsets
AGAIN ;
\ : HF_SETUP
\ 11 need_level \ It appears that Word supplies
\ start: style_names \ this stuff if we don't put it in.
\ pad 3 2dup erase insert: style_names
\ 3 ++> #levels ; \ But we'll keep the code here ready
\ just in case.
: HF_WINDUP
real_text_len text&hf_len = ?EXIT
BEGIN
end: text -4 skip: text 4RETS =?: text
NWHILE
RET +: text
REPEAT
lim: text real_text_len - 2-
dup +L: HF_offsets 1+ +L: HF_offsets
lim: text -> text&hf_len ;
: FIX_HFS_FOR_SECT
save: text
HF_pos >pos: text nolim: text
sect_end_mark chsearch: text
IF pos: text step: text remove_mk <step: text >pos: text THEN
pos: text false find_posn: para_run
(HFs_for_sect)
( NOTE: may need to chk for RETs at end of text here )
step: text
pos: text dup false find_posn: para_run new_item: para_run
\ Leave style# zero for Normal
skip_info: para_run
pos: text -> HF_pos \ Remember where we're up to
restore: text
add_sect_info ;
: HFS_FOR_SECTS \ lim: text points to the first sect marker in text,
\ or to the end of the text proper.
0 +L: sect_offsets
selHFs
BEGIN
step: text real_text_len 1- >lim: text
fix_HFs_for_sect
len: text 0<= ?EXIT
1 skip: text pos: text +L: sect_offsets
SECT chsearch: text drop
AGAIN ;
: TEXT_END_FMT \ Sets up a dummy fmt_run entry for the end of the text,
\ unless there's one there already.
real_text_len true find_posn: fmt_run
pos: fmt_run
IF
^1st: fmt_run itemsize: fmt_run - @ real_text_len = ?EXIT
THEN
\ OK, do it
real_text_len new_item: fmt_run
pad infoSize: fmt_run 2dup $ 80 fill
>nxt$: fmt_run ;
: FIXUP_HFS \ Exported. This is called after UPDATE_HFS, but before
\ we have output anything.
\ It fixes up the section and header/footer info, if
\ there is any, then calls text_end_fmt. This has to be
\ done last, so that any transformations don't move the
\ entry away from real_text_len. Word bombs if it isn't
\ right there!!
reset: text reset: para_run
start: text real_text_len 1-
dup >lim: text dup -> HF_pos -> HF_lim
SECT chsearch: text
GHF? or dup -> GHF?
NIF \ No headers, footers or sections - get out
text_end_fmt EXIT
THEN
0 -> hf_offs new: tmp new: src
HFs_for_sects
hf_windup
text&hf_len +L: sect_offsets
sect_str_out release: tmp release: src
trim_fmt_run trim_para_run
text_end_fmt ;
: HANDLE_SPEC { \ code -- offs addr len } \ Exported. Called when
\ SET_FMT: detects a "special" format.
^1st: fmt_run 12 + c@ -> code code
NIF ( graphic )
^1st: fmt_run 2+ w@ ( offset ) hdr_len +
graphic_fmt + 2- w!
save_offs 1+ graphic_fmt
ELSE ( section or other info )
save_offs
code 1 3 within? nip - \ Add 1 if date, time or page# code
spec_fmt
THEN ;
: GHF_FORMATS_OUT \ Exported. Called to output the final formats
\ if GHF? is true.
text&hf_len real_text_len =
NIF text&hf_len pad 0 str_out THEN
total_text_len text&hf_len =
NIF total_text_len spec_fmt str_out THEN ;
\ ======= Moving H/F text before output ========
: REMOVE_HF
1 skip: text utTbl scan: text drop -1 skip: text
pos: text len: text 2dup
0 fixup: fmt_run 0 fixup: para_run
len: text negate dup ++> HF_lim ++> text&hf_len
delete: text ;
: FIND_HF_PLACE
HF_pos >pos: text
BEGIN
HF_lim >lim: text
utTbl scan: text step: text 0EXIT
1st: text HF_code 2dup > IF 2drop EXIT THEN
= IF remove_HF EXIT THEN
1 skip: text
AGAIN ;
: MOVE_HF { \ hfpos -- }
save: text find_HF_place pos: text -> hfpos
restore: text
pos: text len: text 2dup
hfpos move: fmt_run hfpos move: para_run
text ->: tmp
RET ptr: tmp lim: tmp + 1- c!
pos: text \ Save
len: text negate
dup ++> hfpos dup ++> hf_pos ++> real_text_len \ Adjust for deletion
delete: text
hfpos >pos: text nolim: text
reset: tmp tmp $insert: text
>pos: text ; \ Restore
: NEXT_SECT
save: text HF_lim >pos: text nolim: text
HF_cnt \ We don't skip anything first time in!!
IF
sect_end_mark 1st: text = IF 1 skip: text THEN
THEN
pos: text -> HF_pos
sect_end_mark chsearch: text
NIF
sect_end_mark chinsert: text 1 ++> text&hf_len
pos: text 1-
ELSE
lim: text
THEN
-> HF_lim
restore: text ;
: HFITEM
HF_cnt \ If 1st time in, delimit 1st sect in h/f area
NIF next_sect THEN
true -> GHF?
step: text real_text_len 1- >lim: text
1st: text SECT =
IF
next_sect 1 skip: text
ELSE
1st: text -> HF_code $ 16 chsearch: text
IF 1 more: text THEN
move_HF
THEN ;
: MARK_TEXT_END
reset: text len: text -> text&hf_len
text_end_mark chsearch: text step: text
IF remove_mk THEN
len: text
NIF \ It's straight text, no hdrs/ftrs.
start: text last: text RET <>
IF
RET +: text start: text
THEN
lim: text dup -> real_text_len -> text&hf_len
ELSE \ pos: text points to the char where the
\ final RET will go.
pos: text 1+ -> real_text_len true -> GHF?
THEN
reset: text reset: fmt_run ;
: FIXUP_FTN
ftn_len 0EXIT \ Do nothing if no footnotes
\ were input. Maybe change later.
reset: fmt_run reset: para_run \ For remove_mk calls
start: text real_text_len -> ftn_offs_pos
BEGIN
real_text_len 1- >lim: text
ftn_mark chsearch: text
WHILE
step: text remove_mk -1 ++> real_text_len
pos: text +L: ftn_markers
REPEAT
step: text
lim: text 1- +L: ftn_markers 0 +L: ftn_markers
BEGIN
ftn_mark chsearch: text
WHILE
step: text RET ^1st: text c!
pos: text real_text_len - 1+ +L: ftn_offsets
REPEAT
lim: text real_text_len - dup +L: ftn_offsets
2- -> ftn_len ;
\ UPDATE_HFS (exported) removes any header/footer strings from TEXT, and
\ puts them in the appropriate place in the HF area at the end of the text.
: UPDATE_HFS { \ cnt -- }
reset: fmt_run reset: para_run 0 -> cnt 0 -> HF_cnt
new: tmp mark_text_end
real_text_len 1- -> HF_lim
selHFs \ Select hdr/ftr codes
SECT selChar: utTbl \ and SECT mark
start: text
BEGIN
real_text_len 1- >lim: text
utTbl scan: text \ Any more of that lot?
WHILE
HFitem 1 ++> HF_cnt
REPEAT
release: tmp ;